package cn.lger.icollege.service;

import cn.lger.icollege.dao.AttendanceDao;
import cn.lger.icollege.dao.AttendanceRecordDao;
import cn.lger.icollege.dao.StudentDao;
import cn.lger.icollege.entity.*;
import cn.lger.icollege.util.SecurityResourceUtil;
import cn.lger.icollege.util.excel.ExcelUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Code that Changed the World
 * Pro said
 * Created by Pro on 2018-04-23.
 */
@Service
public class AttendanceService {

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Resource
    private AttendanceDao attendanceDao;
    @Resource
    private StudentDao studentDao;
    @Resource
    private AttendanceRecordDao attendanceRecordDao;
//    @Resource
//    private AttendanceCountDao attendanceCountDao;


    public Page<Attendance> findAllByStudentUsername(Pageable pageable, String username) {
        return attendanceDao.findAllByStudentUsername(pageable, username);
    }

    public Page<Attendance> findAllByStudentUsernameAndTeacherUsername(Pageable pageable, String studnetUsername, String teacherUsername) {
        return attendanceDao.findAllByStudentNameAndTeacherName(pageable, studnetUsername, teacherUsername);
    }


    @Transactional
    public AttendanceRecord saveAttendances(Long classId, String customerName) {
        //在新增考勤的时候给考勤记录表插入一条数据
        Teacher teacher = new Teacher();
        teacher.setUsername(SecurityResourceUtil.getUserDetailsUsername());
        Classroom classroom = new Classroom();
        classroom.setClassId(classId);
        AttendanceRecord attendanceRecord = new AttendanceRecord();
        attendanceRecord.setCreateDate(new Date());
        attendanceRecord.setCustomerName(customerName);
        attendanceRecord.setTeacher(teacher);
        attendanceRecord.setClassroom(classroom);
        attendanceRecord = attendanceRecordDao.save(attendanceRecord);

        //在新增考勤的时候需要给考勤表插入数据并且根据情况对考勤统计表更新数据或者插入数据
        List<Student> students = studentDao.findByClassroom_ClassId(classId);//查找出该班级的所有学生
        List<Attendance> attendances = new ArrayList<Attendance>();
//        List<AttendanceCount> attendanceCounts = new ArrayList<>();
        for (Student student : students) {
            //传入老师和学生的username来构建一个UnionId的实例
//            AttendanceCount.UnionId id = new AttendanceCount.UnionId(SecurityResourceUtil.getUserDetailsUsername(), student.getUsername());
//            Optional<AttendanceCount> optional = attendanceCountDao.findById(id);//根据构建出来的这个id去找对应这个的考勤统计数据
//            AttendanceCount attendanceCount = null;
//            if (optional.isPresent()) {
//                attendanceCount = optional.get();
//                attendanceCount.setOkNum(attendanceCount.getOkNum() + 1);
//            } else {
//                attendanceCount = new AttendanceCount();
//                attendanceCount.setId(id);
//                attendanceCount.setOkNum(1);
//            }
//            attendanceCounts.add(attendanceCount);
            Attendance attendance = new Attendance();
            attendance.setRecord(attendanceRecord);
            attendance.setStudent(student);
            attendance.setTeacher(teacher);
            attendances.add(attendance);
        }
//        attendanceCountDao.saveAll(attendanceCounts);
        attendances = attendanceDao.saveAll(attendances);
        attendanceRecord.setAttendances(attendances);
        return attendanceRecord;
    }

    @Transactional
    public Attendance updateAttendance(String id, Attendance.AttendanceEnum attendanceEnum, String teacherUsername) {
        Attendance attendance = attendanceDao.findByIdAndTeacherUsername(id, teacherUsername);
        if (attendance != null) {
            attendance.setAttendance(attendanceEnum);
            attendance.setModifyDate(new Date());
            attendance = attendanceDao.save(attendance);
            return attendance;
        }
        return null;


//        Attendance attendance = attendanceDao.findByIdAndTeacherUsername(id, teacherUsername);
//        String studentUsername = attendance.getStudent().getUsername();
//        AttendanceCount.UnionId unionId = new AttendanceCount.UnionId(teacherUsername, studentUsername);
//        Optional<AttendanceCount> optional = attendanceCountDao.findById(unionId);
//        if (attendance != null && optional.isPresent()) {
//            AttendanceCount attendanceCount = optional.get();
//            choose(attendance.getAttendance().name(),attendanceCount,-1);
//            boolean flag =choose(attendanceEnum.name(),attendanceCount,1);
//            if(!flag){
//                return attendance;
//            }
//            attendanceCountDao.save(attendanceCount);
//            attendance.setAttendance(attendanceEnum);
//            attendance.setModifyDate(new Date());
//            attendance = attendanceDao.save(attendance);
//            return attendance;
//        }
//        return null;

    }

//    @Transactional
//    public void deleteAttendances(String userDetailsUsername) {
//        attendanceDao.deleteByTeacherUsername(userDetailsUsername);
//    }


//    @Transactional
//    public void deleteAttendancesByClassId(Long classId, String userDetailsUsername) {
////        attendanceDao.deleteByTeacherUsernameAndClassroomClassId(userDetailsUsername,classId);
//    }

//    public Page<Attendance> findAttendances(Pageable pageable, String userDetailsUsername) {
//        return attendanceDao.findAllByTeacherUsername(pageable, userDetailsUsername);
//    }
//
//    public Page<Attendance> findAttendancesByClassId(Pageable pageable, Long classId, String userDetailsUsername) {
//        return attendanceDao.findAllByTeacherUsernameAndClassroomClassId(pageable,userDetailsUsername,classId);
//        return null;
//    }


    @Transactional
    public Integer deleteAttendanceRecordById(String id) {
        return attendanceRecordDao.deleteByIdAndTeacherUsername(id, SecurityResourceUtil.getUserDetailsUsername());


//        Optional<AttendanceRecord> optional=attendanceRecordDao.findById(id);
//        if(optional.isPresent()){
//            AttendanceRecord attendanceRecord=optional.get();
//            Set<Attendance> attendances=attendanceRecord.getAttendances();
//            List<AttendanceCount> attendanceCounts=new ArrayList<>();
//            for(Attendance attendance:attendances){
//                Student student =attendance.getStudent();
//                AttendanceCount.UnionId unionId =new AttendanceCount.UnionId(student.getUsername(),SecurityResourceUtil.getUserDetailsUsername());
//                Optional<AttendanceCount> optional1=  attendanceCountDao.findById(unionId);
//                if(optional1.isPresent()){
//                    AttendanceCount attendanceCount=optional1.get();
//                    choose(attendance.getAttendance().name(),attendanceCount,-1);
//                    attendanceCounts.add(attendanceCount);
//                }else {
//                    return;
//                }
//            }
//            attendanceCountDao.saveAll(attendanceCounts);
//            attendanceRecordDao.deleteById(id);
//        }
    }

    public List<AttendanceRecord> findAttendancesRecordByClassId(Long classId, String userDetailsUsername) {
        return attendanceRecordDao.findByClassroomClassIdAndTeacherUsername(classId, userDetailsUsername, Sort.by(Sort.Direction.DESC, "createDate"));
    }

    public List<AttendanceRecord> findAttendancesRecord(String userDetailsUsername) {
        return attendanceRecordDao.findByTeacherUsername(userDetailsUsername);
    }

    @Transactional
    public Workbook getAttendancesExcel(Long classId, String username) {

        List<Student> students = studentDao.findAllByClassroomClassId(classId, Sort.by("username"));
        Sort sort = Sort.by(Sort.Direction.ASC, "createDate");
        List<AttendanceRecord> records = attendanceRecordDao.findByClassroomClassIdAndTeacherUsername(classId, username, sort);


        return ExcelUtil.writeRowToExcel("sheet1", row -> {

            Cell cell = row.createCell(0);
            cell.setCellValue("学号");
            cell = row.createCell(1);
            cell.setCellValue("姓名");
            for (int i = 0; i < records.size(); i++) {
                row.getSheet().setColumnWidth(i + 2, 5600);
                cell = row.createCell(i + 2);
                cell.setCellValue(simpleDateFormat.format(records.get(i).getCreateDate()));
            }
            row.getSheet().setColumnWidth(row.getLastCellNum(), 13600);
            cell = row.createCell(row.getLastCellNum());
            cell.setCellValue("统计");

        }, (row, index) -> {

            if (index < students.size()) {
                Student student = students.get(index);

                Cell cell = row.createCell(0);
                cell.setCellValue(student.getUsername());
                cell = row.createCell(1);
                cell.setCellValue(student.getName());
                int i = 2;
                for (AttendanceRecord record : records) {
                    cell = row.createCell(i);
                    cell.setCellValue(record.getAttendances().get(index).getAttendance().getChineseName());
                    i++;
                }
                cell = row.createCell(i);
                String str = "出勤：" +
                        attendanceDao.findAttendanceCountByTeacherUsernameAndStudentUsernameAndAttendance(username, student.getUsername(), Attendance.AttendanceEnum.ok) +
                        "；迟到：" +
                        attendanceDao.findAttendanceCountByTeacherUsernameAndStudentUsernameAndAttendance(username, student.getUsername(), Attendance.AttendanceEnum.late) +
                        "；请假：" +
                        attendanceDao.findAttendanceCountByTeacherUsernameAndStudentUsernameAndAttendance(username, student.getUsername(), Attendance.AttendanceEnum.parse) +
                        "；缺勤：" +
                        attendanceDao.findAttendanceCountByTeacherUsernameAndStudentUsernameAndAttendance(username, student.getUsername(), Attendance.AttendanceEnum.no);
                cell.setCellValue(str);

                return true;
            }
            return false;
        });
    }


    private boolean choose(String name, AttendanceCount attendanceCount, int i) {
        boolean flag = true;
        switch (name) {
            case "ok":
                attendanceCount.setOkNum(attendanceCount.getOkNum() + i);
                break;
            case "late":
                attendanceCount.setLateNum(attendanceCount.getLateNum() + i);
                break;
            case "parse":
                attendanceCount.setParseNum(attendanceCount.getParseNum() + i);
                break;
            case "no":
                attendanceCount.setNoNum(attendanceCount.getNoNum() + i);
                break;
            default:
                flag = false;
        }
        return flag;
    }

}
